
#pragma once

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>


#include <sys/time.h>
#include <unistd.h>


class timeElapse {


public:
    static void log(bool isLog, timeval &t1, const std::string TAG = "TAG") {
        struct timeval t2 = {0, 0};
        if (isLog) {
            gettimeofday(&t2, nullptr);
            double timeUsed =
                    (double) (1000000 * (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec)) / 1000000;

            std::cout << TAG << " timeElapse : --------------time(秒):"
                      << timeUsed
                      << std::endl;
        }
    }

    static void log(bool isLog, timeval &t1, float &avgTime, const std::string TAG = "TAG") {
        struct timeval t2 = {0, 0};
        if (isLog) {
            gettimeofday(&t2, nullptr);
            double timeUsed =
                    (double) (1000000 * (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec)) / 1000000;
            if (avgTime != 0.0) {
                avgTime = (avgTime + timeUsed) / 2.0;
            } else {
                avgTime = timeUsed;
            }

            std::cout << TAG << " timeElapseAVG : --------------time(秒):"
                      << avgTime
                      << std::endl;
        }
    }

    static void timeElaspse(const boost::function<int()> &PFN, const boost::function<bool()> &PFN_COND,
                            const std::string TAG = "TAG") {
        struct timeval t1 = {0, 0};
        gettimeofday(&t1, nullptr);
        PFN();
        log(PFN_COND(), t1, TAG);
    }

    static void timeElaspse(const boost::function<int()> &PFN, const bool isLog, const std::string TAG = "TAG") {
        struct timeval t1 = {0, 0};
        gettimeofday(&t1, nullptr);
        PFN();
        log(isLog, t1, TAG);
    }

    static void
    timeElaspse(const boost::function<int()> &PFN, const boost::function<bool()> &PFN_COND, float &avgTime,
                const std::string TAG = "TAG") {
        struct timeval t1 = {0, 0};
        gettimeofday(&t1, nullptr);
        PFN();
        log(PFN_COND(), t1, avgTime, TAG);
    }

    static void
    timeElaspse(const boost::function<int()> &PFN, const bool isLog, float &avgTime, const std::string TAG = "TAG") {
        struct timeval t1 = {0, 0};
        gettimeofday(&t1, nullptr);
        PFN();
        log(isLog, t1, avgTime, TAG);
    }

};